<template>
  <div class="rt-container">
    <el-form :model="tableData" :ref="item &&  item.vModel">
        <div v-for="(row,rIndex) in tableData.rows" class="card" :key="row.id">
            <van-cell class="block-title" :title="row.label" />
            <van-cell-group :border="false">
                <van-cell
                  v-if="col.label"
                  v-for="(col,cIndex) in row.columns"
                  :title="col.label"
                  :key="col.id"
                >
                  <template scope="value">
                      <!-- 单选多选 -->
                      <el-form-item  v-if="col.columnForm.type==1"  style="margin-bottom:0" label=""
                            :prop="'rows.'+rIndex+'.columns.' + cIndex"
                            :rules="selectRules">
                            <el-select
                              @change="(value) =>
                                handleSelectChange(
                                  value,
                                  col,
                                  rIndex,
                                  row.id,col.id,
                                  col.value
                                )"
                              style="width: 70%;"
                              v-model="col.value"
                              :multiple="col.columnForm.multipleSelect"
                              :multiple-limit='col.columnForm.max'
                              popper-class="t-select-popper"
                            >
                              <el-option
                                v-for="(option) in col.columnForm.options"
                                :disabled="option['disabled'+rIndex]"
                                :key="option.value"
                                :value="option"
                                :label="option.label"
                              />
                            </el-select>
                      </el-form-item>

                      <!-- 问答填空 -->
                      <el-form-item  v-if="col.columnForm.type==2 || col.columnForm.type==3"  style="margin-bottom:0" label=""
                          :prop="'rows.'+rIndex+'.columns.' + cIndex"
                          :rules="itemRules">
                          <el-input
                          
                            minlength="1"
                            maxlength="200"
                            v-model.trim="col.value"
                            @change="handleInputChange(row.id,col.id,col.value)"
                          />
                      </el-form-item>
                      <!-- 上传文件 -->
                      <!-- :prop="'columns.' + cIndex+rIndex" -->
                      <el-form-item  v-if="col.columnForm.type==4"  style="margin-bottom:0" label=""
                            :prop="'rows.'+rIndex+'.columns.' + cIndex"
                            :rules="uploadRules"
                            >
                          <el-upload
                          
                            v-bind="{...item}"
                            :multiple="col.columnForm.multipleFile"
                            :limit="col.columnForm.multipleFile ? col.columnForm.fileNum : 1"
                            :accept="col.columnForm.fileType || ''"
                            :on-preview="handlePreview"
                            :on-change="(response, file, fileList) => handleUploadChange(fileList, rIndex, cIndex)"
                            :on-remove="(file, fileList) =>
                              handleRemove(
                                file,
                                fileList,
                                row.id,
                                col.id,
                                'rows.'+rIndex+'.columns.' + cIndex,
                                rIndex,
                                cIndex
                              )"

                            :before-upload="(file, fileList) =>
                              beforeUpload2(
                                file,
                                col,
                                cIndex
                              )"
                            :file-list="col.value2 || []"
                            :on-exceed="(file, fileList) =>
                              handleExceed(col)"
                            :http-request="(file, fileList) =>
                              httpRequest(
                                file,
                                row.id,
                                col.id,
                                'rows.'+rIndex+'.columns.' + cIndex,
                                rIndex,
                                cIndex
                              )"
                          >
                            <el-button  size="mini" type="primary" >
                              上传文件
                            </el-button>

                          </el-upload>
                      </el-form-item>
                  </template>
                </van-cell>
                <van-cell
                  v-else
                  v-for="(col,cIndex) in row.columns"
                  :key="col.id"
                >
                  <template scope="value">
                      <!-- 单选多选 -->
                      <el-form-item  v-if="col.columnForm.type==1"  style="margin-bottom:0" label=""
                            :prop="'rows.'+rIndex+'.columns.' + cIndex"
                            :rules="selectRules">
                            <el-select
                            
                              @change="(value) =>
                                handleSelectChange(
                                  value,
                                  col,
                                  rIndex,
                                  row.id,col.id,
                                  col.value
                                )"
                              style="width: 70%;"
                              v-model="col.value"
                              :multiple="col.columnForm.multipleSelect"
                              :multiple-limit='col.columnForm.max'
                              popper-class="t-select-popper"
                            >
                              <el-option
                                v-for="(option) in col.columnForm.options"
                                :disabled="option['disabled'+rIndex]"
                                :key="option.value"
                                :value="option"
                                :label="option.label"
                              />
                            </el-select>
                      </el-form-item>

                      <!-- 问答填空 -->
                      <el-form-item  v-if="col.columnForm.type==2 || col.columnForm.type==3"  style="margin-bottom:0" label=""
                          :prop="'rows.'+rIndex+'.columns.' + cIndex"
                          :rules="itemRules">
                          <el-input
                          
                            minlength="1"
                            maxlength="200"
                            v-model.trim="col.value"
                            @change="handleInputChange(row.id,col.id,col.value)"
                          />
                      </el-form-item>
                      <!-- 上传文件 -->
                      <!-- :prop="'columns.' + cIndex+rIndex" -->
                      <el-form-item  v-if="col.columnForm.type==4"  style="margin-bottom:0" label=""
                            :prop="'rows.'+rIndex+'.columns.' + cIndex"
                            :rules="uploadRules"
                            >
                          <el-upload
                          
                            v-bind="{...item}"
                            :multiple="col.columnForm.multipleFile"
                            :limit="col.columnForm.multipleFile ? col.columnForm.fileNum : 1"
                            :accept="col.columnForm.fileType || ''"
                            :on-preview="handlePreview"
                            :on-change="(response, file, fileList) => handleUploadChange(fileList, rIndex, cIndex)"
                            :on-remove="(file, fileList) =>
                              handleRemove(
                                file,
                                fileList,
                                row.id,
                                col.id,
                                'rows.'+rIndex+'.columns.' + cIndex,
                                rIndex,
                                cIndex
                              )"

                            :before-upload="(file, fileList) =>
                              beforeUpload2(
                                file,
                                col,
                                cIndex
                              )"
                            :file-list="col.value2 || []"
                            :on-exceed="(file, fileList) =>
                              handleExceed(col)"
                            :http-request="(file, fileList) =>
                              httpRequest(
                                file,
                                row.id,
                                col.id,
                                'rows.'+rIndex+'.columns.' + cIndex,
                                rIndex,
                                cIndex
                              )"
                          >
                            <el-button  size="mini" type="primary" >
                              上传文件
                            </el-button>

                          </el-upload>
                      </el-form-item>
                  </template>
                </van-cell>
            </van-cell-group>
        </div>
    </el-form>

  </div>
</template>

<script>
import mixin from '../mixin'
import uploadMixin from '../uploadMixin'
import {jsonSimpleClone} from "../../../utils"
import axios from 'axios'
import 'vant/lib/cell/style'
import 'vant/lib/cell-group/style'

import {Cell, CellGroup} from 'vant';
const axiosSourceMap = new Map()
export default {
  name: 'MobileMatrixTable',
  mixins: [mixin,uploadMixin],
  components: {
    VanCell: Cell,
    VanCellGroup: CellGroup
  },
  props: {
    table: {
      type: Object,
      default: () => {
      }
    }
  },
  data() {
    let handleUpload= (rule, value, callback) => {
      console.log(value.value,'upload---value')
      this.$nextTick(function(){
        if(value.columnForm.required){
              if (value.value && value.value.length) {
                callback()
              }else{
                callback(new Error('请选择'))
              }
        }else{
          callback()
        }
      })
    }
    let handleDuplicate = (rule, value, callback) => {
      console.log(value,'value填空')
      let validator = ''
      let text=''
      switch (value.columnForm.testType) {
        case 1:
          validator = ''
          break
        case 2:
        // 阿拉伯数字
          validator = '^[0-9]+$'
          text="请输入阿拉伯数字格式"
          break
        case 3:
        // 固定电话
          validator = '^[0-9]{3,4}-[0-9]{7,8}$'
          text="请输入固定电话格式"
          break
        case 4:
        // 手机号
          validator = '^1[3-9][0-9]{9}$'
          text="请输入手机号格式"
          break
        case 5:
        // 邮政编码
          validator = '^[1-9][0-9]{5}$'
          text="请输入邮政编码格式"
          break
        case 6:
        // Email
          validator = '^([a-zA-Z0-9]+[-_\.]?)+@[a-zA-Z0-9]+\.[a-z]+$'
          text="请输入Email格式"
          break
        case 7:
        // URL
        validator = "[a-zA-z]+://[^\s]*";
          // validator = '^(?:(?:https?)://)(?:(?:1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|[1-9])(?:\.(?:1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)){2}(?:\.(?:1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*)(?::([1-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5]))?(?:/\S*)?$'
          text="请输入URl格式"
          break
        case 8:
        // 身份证
          validator = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/
          text="请输入身份证格式"
          break
        case 9:
          // 日期
          // 2022-07-08
          validator = '^([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8])))+$'
          text="请输入日期格式"
          break
        case 10:
        // 中文
          validator = '^[\u4e00-\u9fa5]+$'
          text="请输入中文格式"
          break
        case 11:
        // 中英文
          validator = '^[\u4e00-\u9fa5a-zA-Z]+$'
          text="请输入中英文格式"
          break
      }
      if(value.columnForm.required){
          if (value.value) {
            if(!new RegExp(validator).test(value.value)){
              callback(new Error(text))
            }else{
              callback()
            }
          } else{
            callback(new Error('请输入内容'))
          }
      }else{
        if (value.value) {
          if(!new RegExp(validator).test(value.value)){
            callback(new Error(text))
          }else{
            callback()
          }
        }else{
          callback()
        }
      }
    }
    let handleSelect = (rule, value, callback) => {
      console.log(value,'value')
      this.$nextTick(function(){
        if(value.columnForm.required){
            if (value.value && _.isArray(value.value) && value.value.length) {
              callback()
            }else if(value.value && value.value['label']){
              callback()
            }else{
              callback(new Error('请选择'))
            }
        }else{
          callback()
        }
      })
    }
    return {
      dataValue: [],
      values:[],
      selectRules:[{trigger:'change',validator:handleSelect}],
      itemRules:[{trigger:'blur',validator:handleDuplicate}],
      uploadRules:[{trigger:'change',validator:handleUpload}],
      flag:'',
      singleOrAll:true,
      tableData:{
        rows:[]
      }
    }
  },
  watch: {
    table: {
      handler(value) {
        this.initValue()
        var table =JSON.parse(JSON.stringify(value))
        console.log(table,'table-----')
        this.tableData.rows=[]
        table.rows.forEach(item => {
          this.$set(item,'columns',JSON.parse(JSON.stringify(this.table.columns)))
          item.columns.forEach(item2 => {
            // el-select绑定的数据为null，就会触发change事件，从而开启了表单校验
            if(item2.columnForm.type == 1){
              if(item2.columnForm.multipleSelect){
                this.$set(item2,'value',(this.dataValue[item.id][item2.id]==null ? [] : this.dataValue[item.id][item2.id]))
              }else{
                this.$set(item2,'value',(this.dataValue[item.id][item2.id]==null ? {} : this.dataValue[item.id][item2.id]))
              }
            }else{
              this.$set(item2,'value',this.dataValue[item.id][item2.id])
              if(item2.columnForm.type == 4){
                this.$set(item2, 'value2', this.dataValue[item.id][item2.id])
              }
            }

          })
          this.tableData.rows.push(item)
        })
      },
      deep: true
    }
  },
  computed: {
  },
  created() {
    this.initValue()
  },
  mounted(){
    console.log(this.table,'table')
      this.table.rows.forEach(item => {
        this.$set(item,'columns',JSON.parse(JSON.stringify(this.table.columns)))
        item.columns.forEach(item2 => {
          // el-select绑定的数据为null，就会触发change事件，从而开启了表单校验
          if(item2.columnForm.type == 1){
            if(item2.columnForm.multipleSelect){
              this.$set(item2,'value',(this.dataValue[item.id][item2.id]==null ? [] : this.dataValue[item.id][item2.id]))
            }else{
              this.$set(item2,'value',(this.dataValue[item.id][item2.id]==null ? {} : this.dataValue[item.id][item2.id]))
            }
          }else{
            this.$set(item2,'value',this.dataValue[item.id][item2.id])
            if(item2.columnForm.type == 4){
              this.$set(item2, 'value2', this.dataValue[item.id][item2.id])
            }
          }

        })
        this.tableData.rows.push(item)
      })
  },
  methods: {
    aaa(){
        this.$refs[this.item.vModel].validate((valid) => {
            if (valid) {
            } else {
              return false;
            }
        });
    },
    handlePreview(file) {
      console.log(file,'file')
      const elink = document.createElement('a')
      elink.style.display = 'none'
      if (!file.url) {
        file.url = URL.createObjectURL(file.raw);
      }
      elink.href = file.url
      var name = file.name.replace(/<[^>]+>/g, '')
      console.log(name,'eeeeeeeee')
      elink.download=name
      document.body.appendChild(elink)
      elink.click()
      document.body.removeChild(elink)
      // window.open(file.url)
    },
    handleExceed(col) {
      if(col.columnForm.multipleFile){
        this.msgError('最多只能上传' + col.columnForm.fileNum + '个文件')
      }else{
        this.msgError('最多只能上传1个文件')
      }

    },
    handleUploadChange(fileList, rIndex, cIndex) {
      this.tableData.rows[rIndex].columns[cIndex].value2 = fileList
    },
    // 文件删除
    handleRemove(file,fileList,row,col,flag,rIndex,cIndex) {
      let tempList = jsonSimpleClone(this.dataValue[row][col])
      _.remove(tempList, function (item) {
        return item.uid === file.uid
      })
      this.tableData.rows[rIndex].columns[cIndex].value2 = fileList
      this.tableData.rows[rIndex].columns[cIndex].value = tempList
      this.dataValue[row][col] = tempList
      this.handleChange()
      this.flag=flag
      this.$nextTick(function(){
        this.$refs[this.item.vModel].validateField(this.flag)
      })
      this.$store.dispatch('form/uploadStatusMap', {
        [file.uid]: 3
      })
      if (axiosSourceMap.has(file.raw)) {
        axiosSourceMap.get(file.raw).abort()
      }
    },
    // 初始化矩阵value为二维数组
    initValue() {
      let initValue = {}
      this.table.rows.forEach(row => {
        initValue[row.id]={}
        this.table.columns.forEach(col => {
          if (this.value[row.id]&&this.value[row.id][col.id]) {
            initValue[row.id][col.id] = this.value[row.id][col.id]
          } else {
            initValue[row.id][col.id] = null
          }
        })
      })
      this.dataValue = initValue
      console.log(this.dataValue,'this.dataValue')


    },
    handleChange() {
      this.value = this.dataValue
      this.$emit('change', this.dataValue)
    },
    httpRequest(item, row, col, flag, rIndex, cIndex) {
      const formData = new FormData()
      formData.append('file', item.file)

      this.$store.dispatch('form/uploadStatusMap', {
        [item.file.uid]: 1
      })
      const xhr = new XMLHttpRequest();
      xhr.timeout = 3600000
      xhr.onload = (e) => {
        if (xhr.status !== 200) {
          console.error(`Error ${xhr.status}: ${xhr.statusText}`);
        } else {
            const res = JSON.parse(xhr.responseText)
            const {data} = res
            let oldFileList = this.dataValue[row][col]
            if (!oldFileList) {
              oldFileList = []
            }
            oldFileList.push({
              name: item.file.name,
              url: data,
              uid:item.file.uid
            })
            this.tableData.rows[rIndex].columns[cIndex].value = oldFileList
            this.dataValue[row][col] = oldFileList
            this.handleChange()
            this.flag = flag
            this.$nextTick(function () {
              this.$refs[this.item.vModel].validateField(this.flag)
            })
            item.onSuccess()
        }

        this.$store.dispatch('form/uploadStatusMap', {
          [item.file.uid]: 2
        })
        axiosSourceMap.delete(item.file)
      }
      xhr.upload.onprogress = (e) => { //监听onprogress事件获取进度
        if (e.lengthComputable) {
          const percentComplete = e.loaded / e.total * 100;
          item.onProgress({status: 'uploading', percent: percentComplete})
        }
      };
      xhr.open('POST', `${item.action}?_=${new Date().getTime()}`);
      xhr.send(formData);
      axiosSourceMap.set(item.file, xhr)
    },

    handleSelectChange(val,col,rIndex,rowId,colId,value){
      this.dataValue[rowId][colId]=value
      this.singleOrAll = true
      const {multipleOption, withExclusiveChoice,options} = col.columnForm
      if (val.length) {
        if(withExclusiveChoice){
          const changeVal = val[val.length - 1]
          // 当前选中项的索引
          const isChecked = options.findIndex(
            (e) => e.value === changeVal.value
          )
          // 是否是互斥,不是返回-1，是的话返回对应的索引
          const isExclusive = multipleOption.findIndex(
            (e) => e.value === changeVal.value
          )
          // 选中 并且 互斥
          if (isChecked > -1 && isExclusive > -1) {
            options.forEach((item,index)=>{
                  if(index === isChecked){
                    item['disabled'+rIndex]=false
                    // this.$set(item,'disabled'+rIndex,false)
                  }else{
                    // this.$set(item,'disabled'+rIndex,true)
                    item['disabled'+rIndex]=true
                  }
            })
          }
          // 选中 并且 不互斥
          if (isChecked > -1 && isExclusive === -1) {
            // 不是互斥的值
            const noExclusive = options.findIndex(
              (e) => e.value === changeVal.value
            )
            options.forEach((item,index)=>{
                  if(index === noExclusive){
                    // this.$set(item,'disabled'+rIndex,false)
                    item['disabled'+rIndex]=false
                  }else{
                    multipleOption.forEach((item2,index2)=>{
                      if(item.value == item2.value){
                        // this.$set(item,'disabled'+rIndex,true)
                        item['disabled'+rIndex]=true
                      }
                    })
                  }
            })
            if(col.columnForm.min){
              if(val.length<col.columnForm.min){
                this.$message.warning("最少要选择"+col.columnForm.min+"个选项");
              }
            }
            if(col.columnForm.max){
              if(val.length>col.columnForm.max){
                this.$message.warning("最多只能选择"+col.columnForm.max+"个选项");
              }
            }
          }
        }else{
          if(col.columnForm.min){
            if(val.length<col.columnForm.min){
              this.$message.warning("最少要选择"+col.columnForm.min+"个选项");
            }
          }
          if(col.columnForm.max){
            if(val.length>col.columnForm.max){
              this.$message.warning("最多只能选择"+col.columnForm.max+"个选项");
            }
          }
        }

      }else{
        options.forEach((item,index)=>{
          // this.$set(item,'disabled'+rIndex,false)
          item['disabled'+rIndex]=false
        })

      }
      this.handleChange()
    },
    handleInputChange(row,col,value){
      this.dataValue[row][col]=value
      this.handleChange()
    },
  },
}
</script>

<style lang="scss">
.leftAlign th, .leftAlign td {
    text-align: left;
}
.rightAlign th, .rightAlign td {
    text-align: right;
}
.centerAlign th, .centerAlign td {
    text-align: center;
}
.van-cell{
  min-height:68px
}
</style>
